package com.javafactroy.kunlong.bip.icp.message.test.netty.handler.client;

import com.google.common.cache.*;
import com.javafactroy.kunlong.bip.icp.common.consts.IConfig;
import com.javafactroy.kunlong.bip.icp.message.test.base.TMsgResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import com.javafactroy.kunlong.bip.icp.message.base.iface.IMessage;

import java.util.concurrent.TimeUnit;

@Repository
@Slf4j
public class TMsgSyncFutureMngr {
    protected static LoadingCache<String, TMsgSyncFuture> futureCache = CacheBuilder.newBuilder()
            //设置缓存容器的初始容量为10
            .initialCapacity(100)
            // maximumSize 设置缓存大小
            .maximumSize(10000)
            //设置并发级别为20，并发级别是指可以同时写缓存的线程数
            .concurrencyLevel(20)
            // expireAfterWrite设置写缓存后8秒钟过期
            .expireAfterWrite(8, TimeUnit.SECONDS)
            //设置缓存的移除通知
            .removalListener(new RemovalListener<Object, Object>() {
                @Override
                public void onRemoval(RemovalNotification<Object, Object> notification) {
                    log.debug("LoadingCache: {} was removed, cause is {}", notification.getKey(),
                            notification.getCause());
                }
            })
            //build方法中可以指定CacheLoader，在缓存不存在时通过CacheLoader的实现自动加载缓存
            .build(new CacheLoader<String, TMsgSyncFuture>() {
                @Override
                public TMsgSyncFuture load(String key) throws Exception {
                    // 当获取key的缓存不存在时，不需要自动添加
                    return null;
                }
            });

    public static void put(String msgId, TMsgSyncFuture syncFuture) {
        futureCache.put(msgId, syncFuture);

    }

    public static void ackSyncMsg(IMessage msg) {

        log.info("ACK确认信息: {}", msg);
        // 从缓存中获取数据
        TMsgSyncFuture<IMessage> syncFuture = futureCache.getIfPresent(msg.getMessageId());
        // 如果不为null, 则通知返回
        if (syncFuture != null) {
            syncFuture.setResponse(msg);
            futureCache.invalidate(msg);
        }
    }

    public static void ackSyncMsgErr(IMessage msg) {
        TMsgResp resp = TMsgResp.buildMsgError();
        resp.getHeader().setMessageId(msg.getMessageId());
        resp.setMsgState(IConfig.INettyConst.MSG_State.MSG_SEND_ERR);
        log.info("ACK确认信息: {}", resp);
        // 从缓存中获取数据
        TMsgSyncFuture<IMessage> syncFuture = futureCache.getIfPresent(resp.getMessageId());

        if (syncFuture != null) {
            syncFuture.setResponse(resp);
            futureCache.invalidate(resp);
        }
    }
}
